package edu.colorado.karl.databases;

import java.io.Serializable;
import java.util.Date;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.data.time.TimeSeriesCollection;

import de.laures.cewolf.DatasetProduceException;
import de.laures.cewolf.DatasetProducer;

/**
 * ChartDataProducer is a JavaBean which handles the fetching and formatting of
 * data to be plotted in the Long-Term state page.  
 *  
 * @author Eric Hoffman
 * @version 3/2/08
 */
public class ChartDataProducer implements DatasetProducer, Serializable { 
	//other not used implements: CategoryToolTipGenerator, CategoryItemLinkGenerator,
	private String[] sensorList;
	private LongTermDatabase db;
	private static final Log log = LogFactory.getLog(ChartDataProducer.class);
	private TimeSeriesCollection ts;
	private Date startDate;
	private Date endDate;
	private String errorMessage;

	
	/**
	 * ChartDataProducer default constructor
	 */
	public ChartDataProducer() {
		sensorList = new String[] {""};
		errorMessage = "";
		ts = new TimeSeriesCollection();
		startDate = new Date();
		endDate = new Date();
		db = new LongTermDatabase();
	}
	
	/**
	 * Returns the requested data in the proper format to the Long-Term State JSP.
	 * @param params Optional parameters for the chart.
	 * @return A TimeSeriesCollection containing data to be plotted is returned.
	 */
	public Object produceDataset(Map params) throws DatasetProduceException {
		log.debug("produceDataset() getting data.");
					
	    return this.ts;
	}
	
	/**
	 * CeWolf finalize function.
	 */
	protected void finalize() throws Throwable {
		super.finalize();
		log.debug(this + "is finalized.");
	}
	
	/**
	 * Determines when the producer's data should be invalidated.
	 * @param params 	parameters from the jsp - unused.
	 * @param date	the timestamp the request was issued.
	 * @return false when the data is old and chart cannot be reused,
	 *  or true if chart can be reused.
	 */
	public boolean hasExpired(Map params, Date date) {
		log.debug(getClass().getName() + "hasExpired()");
        return (System.currentTimeMillis() - date.getTime())  > 2500;
        										//2500ms = 2.5seconds
    }
	
	/**
	 * Returns to CeWolf a unique producer ID for multiple invocations.
	 * @return the producer ID.
	 */
	public String getProducerId() {
        return "SoftCORE Long-Term State Data Producer";
    }
	
	/**
	 * Sets the starting timestamp for data to be charted
	 * @param d the start date
	 */
	public void setStartDate(Date d) {
		this.startDate = d;
		java.sql.Timestamp tSStart = new java.sql.Timestamp(d.getTime());
		log.debug("Start Date is: " + d.toString());
	}
	
	/**
	 * Sets the ending timestamp for data to be charted
	 * @param d the end date
	 */
	public void setEndDate(Date d) {
		this.endDate = d;
		log.debug("End Date is: " + d.toString());
	}
	
	/**
	 * Sets which sensors' data should be fetched.
	 * @param value	a zero based list of Sensor ID numbers.
	 */
	public void setSensorList(String[] value) {		
		sensorList = value;
		this.ts = db.getValuesForTimeRange(startDate, endDate, sensorList);
		log.debug("Set new TimeSeriesCollection");
	}
	
	/**
	 * Returns an error message if no data was within the date selection
	 * @return The error message or an empty string if no error
	 */
	public String getErrorMessage() {
		for(int i=0; i<ts.getSeriesCount();i++) {
			if(ts.getItemCount(i) > 1) {
				return "";
			}
		}
		return "No data to display for selected sensors\nwithin that date range.";
	}
}
